#include <stdio.h>
#include <string.h>

#include <errno.h>
#include <iconv.h>

static int long_iconv(char *encfrom, char *encto, char *bufin, char *bufout)
{
       char *sin = NULL, *sout = NULL;
       size_t lenin = 0, lenout = 0;
       int ret = 0;
       iconv_t c_pt = NULL;

       if ((c_pt = iconv_open(encto, encfrom)) == (iconv_t)(-1))
              return -1; 

       lenin = strlen(bufin)+1;
       lenout = (strlen(bufin)+1)*10;
       sin = bufin;
       sout = bufout;
       ret = iconv(c_pt, (char **)&sin, &lenin, &sout, &lenout);
       
       iconv_close(c_pt);

       return ret == (size_t)-1 ? -1 : 0 ;

}

void show_ip(unsigned char *ip)
{
	char buf[1024] = {0};
	snprintf(buf, sizeof(buf), "%02X %02X %02X %02X", ip[0], ip[1], ip[2], ip[3]);
	printf("%-20s", buf);
}

int read_index(FILE *pf, int *start, int *stop, unsigned char *buf, int buf_size)
{
	if(NULL != pf && NULL != buf && *start <= *stop && 7 <= buf_size)
	{
		fseek(pf, *start, SEEK_SET);
		fread(buf, 7, 1, pf);
		*start += 7;
		return 0;
	}
	return -1;
}

int read_record(FILE *pf, int record, unsigned char *buf, int buf_size)
{
	if(NULL != pf && NULL != buf && 8 <= record && 8 <= buf_size)
	{
		fseek(pf, record, SEEK_SET);
		fread(buf, buf_size, 1, pf);
		return 0;
	}
	return -1;
}

int paser_record(FILE *pf, unsigned char *src, int buf_size)
{
	int record = 0;
	int ret = 0;
	char dest[1024] = {0};
	if(0x3 > src[4])
	{
		record = src[5] | (src[6] << 8) | (src[7] << 16);
		read_record(pf, record, src, buf_size);
		ret = long_iconv("GB2312", "UTF-8", (char *)src, dest);
	}
	else
	{
		ret = long_iconv("GB2312", "UTF-8", (char *)&src[4], dest);
	}
	printf("%s\n", 0 == ret ? dest : strerror(errno));
	return 0;
}

int main(int argc, char **argv)
{
	int start = 0;
	int stop = 0;

	int record = 0;

	unsigned char buf[1024] = {0};
	FILE *pf = fopen("./qqwry.dat", "r");

	if(NULL != pf)
	{
		fread(&start, sizeof(start), 1, pf);
		fread(&stop, sizeof(stop), 1, pf);

		while(0 == read_index(pf, &start, &stop, buf, sizeof(buf)))
		{
			record = buf[4] | (buf[5] << 8) | (buf[6] << 16);
			show_ip(buf);
			read_record(pf, record, buf, sizeof(buf));
			show_ip(buf);
			//printf("0x%X\t\t", record);
			paser_record(pf, buf, sizeof(buf));
		}
	}
	return 0;
}
